const func = {};
export default func;
/**
 * <@enum=list key="key" value="value"></>
 */
func['enum'] = {type: 'enum', async func(node, scope, next) {
	await this.repeat(node.list, scope, node.value, {value: node.param.value, key: node.param.key});
}}

/**
 * <@if=``script``>
 * <|elseif=``script``>
 * <|else>
 * </>
 */
func['if'] = {type: 'if', async func(node, scope, next) {
	let thisnode = node;
	let childScope = this.scope(scope);
	for (let i = 0,l = node.sub.length, list = node.sub;i <= l; i++) {
		if (await thisnode.value.exec(childScope)) {
			return await this.parseList(thisnode.list, childScope);
		}
		if (i >= l) {
			break;
		}
		thisnode = list[i];
		if (thisnode.name === 'else') {
			return await this.parseList(thisnode.list, childScope);
		} else if (thisnode.name !== 'elseif') {
			break;
		}
	}
}}


/**
 * <@while=``script``></>
 */
func['while'] = {type: 'while', async func({value, list}, scope, next) {
	const symbol = this.symbol;
	const Scope = this.scope;
	while(await value.exec(scope)) {try {
		await this.parseList(list, Scope(scope));
	}catch(sign) {
		if (sign === symbol.BREAK) {
			return ;
		} else if (typeof sign === "object" && sign.type === symbol.BREAK) {
			if (!sign.number || sign.number <= 0) {
				return ;
			}
			sign.number--;
			if(sign.number <= 0) {
				throw symbol.BREAK;
			}
			return ;
		} else if (sign && sign.type === symbol.CONTINUE) {
			if (sign.number > 0) {
				sign.number--;
				if(sign.number <= 0) {
					throw symbol.CONTINUE;
				}
				throw sign;
			}
		} else if(sign !== symbol.CONTINUE) {
			throw sign;
		}
	}}
}}

/**
 * <@break/>
 */
func['break'] = {type: 'break', async func(node, scope, next) {
	throw this.symbol.BREAK;
}}

/**
 * <@continue/>
 */
func['continue'] = {type: 'continue', async func(node, scope, next) {
	throw this.symbol.CONTINUE;
}}
